package io.chenglicun.modules.clc.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.chenglicun.common.entity.BaseEntity;
import io.chenglicun.common.page.PageData;
import io.chenglicun.common.service.impl.CrudServiceImpl;
import io.chenglicun.common.utils.ConvertUtils;
import io.chenglicun.modules.clc.dao.ClcUserDeptDao;
import io.chenglicun.modules.clc.dto.ClcUserDeptDTO;
import io.chenglicun.modules.clc.entity.ClcUserDeptEntity;
import io.chenglicun.modules.clc.service.ClcUserDeptService;
import io.chenglicun.modules.sys.dao.SysDeptDao;
import io.chenglicun.modules.sys.dao.SysUserDao;
import io.chenglicun.modules.sys.entity.SysDeptEntity;
import io.chenglicun.modules.sys.entity.SysUserEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户部门关联表
 *
 * @author HB 137664951@qq.com
 * @since 1.0 2023-11-28
 */
@Service
public class ClcUserDeptServiceImpl extends CrudServiceImpl<ClcUserDeptDao, ClcUserDeptEntity, ClcUserDeptDTO> implements ClcUserDeptService {
    @Autowired
    private SysUserDao userDao;

    @Autowired
    private SysDeptDao deptDao;

    @Override
    public QueryWrapper<ClcUserDeptEntity> getWrapper(Map<String, Object> params) {
        QueryWrapper<ClcUserDeptEntity> wrapper = new QueryWrapper<>();

        Object userId = params.get("userId");
        Object deptId = params.get("deptId");
        wrapper.eq(ObjectUtil.isNotEmpty(userId), "user_id", userId);
        wrapper.eq(ObjectUtil.isNotEmpty(deptId), "dept_id", deptId);

        return wrapper;
    }

    @Override
    public PageData<ClcUserDeptDTO> page(Map<String, Object> params) {
        //分页
        IPage<ClcUserDeptEntity> page = getPage(params, "clc_user_dept.create_date", false);
        //查询
        List<ClcUserDeptEntity> list = baseDao.getList(params);

        PageData<ClcUserDeptDTO> pageData = getPageData(list, page.getTotal(), ClcUserDeptDTO.class);

        List<ClcUserDeptDTO> dtos = pageData.getList();

        for (ClcUserDeptDTO dto : dtos) {
            dto.setDeptName(getDeptName(dto.getDeptId(), dto.getDeptName(), deptDao.selectList(new QueryWrapper<>())));
        }

        return pageData;
    }

    @Override
    @Transactional
    public void saveOrUpdate(Long userId, List<ClcUserDeptDTO> deptList) {
        //先删除用户部门关系
        deleteByUserIds(new Long[]{userId});

        //用户没有一个部门的情况
        if (CollUtil.isEmpty(deptList)) {
            return;
        }

        //保存用户部门关系
        for (ClcUserDeptDTO userDeptDTO : deptList) {
            userDeptDTO.setUserId(userId);

            //保存
            save(userDeptDTO);
        }
    }

    @Override
    @Transactional
    public void deleteByUserIds(Long[] userIds) {
        baseDao.delete(new QueryWrapper<ClcUserDeptEntity>().lambda().in(ClcUserDeptEntity::getUserId, Arrays.asList(userIds)));
    }

    @Override
    public List<ClcUserDeptDTO> getByUserIds(Long... userIds) {
        List<ClcUserDeptEntity> entities = baseDao.selectList(new QueryWrapper<ClcUserDeptEntity>().lambda().in(ClcUserDeptEntity::getUserId, Arrays.asList(userIds)));
        List<ClcUserDeptDTO> dtos = ConvertUtils.sourceToTarget(entities, ClcUserDeptDTO.class);

        List<Long> deptIds = dtos.stream().map(ClcUserDeptDTO::getDeptId).filter(Objects::nonNull).collect(Collectors.toList());

        List<SysUserEntity> userEntities = userDao.selectList(new QueryWrapper<SysUserEntity>().lambda().in(BaseEntity::getId, Arrays.asList(userIds)));
        List<SysDeptEntity> deptEntities = deptIds.size() == 0 ? new ArrayList<>() : deptDao.selectList(new QueryWrapper<SysDeptEntity>().lambda().in(BaseEntity::getId, deptIds));

        for (ClcUserDeptDTO dto : dtos) {
            dto.setUserName(
                    userEntities.stream().filter(t -> t.getId().equals(dto.getUserId())).map(SysUserEntity::getRealName).findFirst().orElse(null));
            dto.setDeptName(
                    deptEntities.stream().filter(t -> t.getId().equals(dto.getDeptId())).map(SysDeptEntity::getName).findFirst().orElse(null));
            dto.setDeptName(getDeptName(dto.getDeptId(), dto.getDeptName(), deptDao.selectList(new QueryWrapper<>())));
        }


        return dtos;
    }

    private String getDeptName(Long deptId, String deptName, List<SysDeptEntity> deptEntities) {
        SysDeptEntity sysDeptEntity = deptEntities.stream().filter(t -> t.getId().equals(deptId)).findFirst().orElse(null);
        if (sysDeptEntity != null){

            Long pid = sysDeptEntity.getPid();
            if (pid != null && pid != 0) {
                SysDeptEntity parentEntity = deptEntities.stream().filter(t -> t.getId().equals(pid)).findFirst().orElse(null);
                if (parentEntity != null) {
                    String parentName = parentEntity.getName();
                    deptName = parentName + "/" + deptName;
                }
                deptName = getDeptName(pid, deptName, deptEntities);
            }
        }
        return deptName;
    }
}